
package com.lyyzoo.data.dao;

import com.lyyzoo.data.domain.Page;
import com.lyyzoo.util.Collections;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class SimpleDao<T, ID extends Serializable> {
    @Autowired
    protected SessionFactory sessionFactory;
    protected Class<T> entityClass;
    protected String entityName;

    public SimpleDao() {
        Type genType = this.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType)genType).getActualTypeArguments();
        this.entityClass = (Class)params[0];
        this.entityName = this.entityClass.getSimpleName();
    }

    public SessionFactory getSessionFactory() {
        return this.sessionFactory;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    private Session getCurrentSession() {
        return this.sessionFactory.getCurrentSession();
    }

    public <S extends T> S save(S entity) {
        this.getCurrentSession().save(entity);
        return entity;
    }

    public <S extends T> List<S> save(Iterable<S> entities) {
        List<S> result = new ArrayList();
        if (entities == null) {
            return result;
        } else {
            Iterator var3 = entities.iterator();

            while(var3.hasNext()) {
                Object entity = var3.next();
                result.add(this.save((S)entity));
            }

            return result;
        }
    }

    public T get(ID id) {
        return this.getCurrentSession().get(this.entityClass, id);
    }

    public T get(Map<String, Object> filter) {
        List<T> objs = this.find(filter);
        return objs.size() > 0 ? objs.get(0) : null;
    }

    public List<T> find() {
        String hql = "FROM " + this.entityName;
        Query q = this.getCurrentSession().createQuery(hql);
        return q.list();
    }

    public List<T> find(String key, Object value) {
        Map<String, Object> filter = new HashMap();
        filter.put(key, value);
        return this.find(filter);
    }

    public List<T> find(Map<String, Object> filter) {
        StringBuilder _hql = new StringBuilder("FROM " + this.entityName);
        List<Object> params = new ArrayList();
        if (Collections.isNotEmpty(filter)) {
            Set<Entry<String, Object>> set = filter.entrySet();
            Iterator var5 = set.iterator();

            while(var5.hasNext()) {
                Entry<String, Object> entry = (Entry)var5.next();
                _hql.append(" AND " + (String)entry.getKey() + " = ?");
                params.add(entry.getValue());
            }
        }

        String hql = _hql.toString().replaceFirst("AND", "WHERE");
        Query query = this.getCurrentSession().createQuery(hql);

        for(int i = 0; i < params.size(); ++i) {
            query.setParameter(i, params.get(i));
        }

        return query.list();
    }

    public <S extends T> S update(S entity) {
        this.getCurrentSession().update(entity);
        return entity;
    }

    public <S extends T> List<S> update(Iterable<S> entities) {
        List<S> result = new ArrayList();
        if (entities == null) {
            return result;
        } else {
            Iterator var3 = entities.iterator();

            while(var3.hasNext()) {
                Object entity = var3.next();
                result.add(this.update((S)entity));
            }

            return result;
        }
    }

    public <S extends T> S saveOrUpdate(S entity) {
        this.getCurrentSession().saveOrUpdate(entity);
        return entity;
    }

    public <S extends T> List<S> saveOrUpdate(Iterable<S> entities) {
        List<S> result = new ArrayList();
        if (entities == null) {
            return result;
        } else {
            Iterator var3 = entities.iterator();

            while(var3.hasNext()) {
                Object entity = var3.next();
                result.add(this.saveOrUpdate((S)entity));
            }

            return result;
        }
    }

    public void delete(ID id) {
        T entity = this.get(id);
        this.delete(entity);
    }

    public void delete(ID[] ids) {
        Serializable[] var2 = ids;
        int var3 = ids.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            Serializable id = var2[var4];
            T entity = this.get((ID)id);
            this.delete(entity);
        }

    }

    public void delete(T entity) {
        this.getCurrentSession().delete(entity);
    }

    public void delete(Iterable<T> entities) {
        Iterator var2 = entities.iterator();

        while(var2.hasNext()) {
            Object entity = var2.next();
            this.delete((T)entity);
        }

    }

    public void merge(T entity) {
        this.getCurrentSession().merge(entity);
    }

    public Page<T> page(int pageNumber, int pageSize) {
        return this.page((Map)null, pageNumber, pageSize);
    }

    public Page<T> page(Map<String, Object> filter, int pageNumber, int pageSize) {
        StringBuilder _hql = new StringBuilder("FROM " + this.entityName);
        List<Object> params = new ArrayList();
        if (Collections.isNotEmpty(filter)) {
            Set<Entry<String, Object>> set = filter.entrySet();
            Iterator var7 = set.iterator();

            while(var7.hasNext()) {
                Entry<String, Object> entry = (Entry)var7.next();
                _hql.append(" AND " + (String)entry.getKey() + " = ?");
                params.add(entry.getValue());
            }
        }

        String hql = _hql.toString().replaceFirst("AND", "WHERE");
        Query query = this.getCurrentSession().createQuery(hql);

        int offset;
        for(offset = 0; offset < params.size(); ++offset) {
            query.setParameter(offset, params.get(offset));
        }

        offset = pageSize * (pageNumber - 1);
        List<T> entitys = query.setFirstResult(offset).setMaxResults(pageSize).list();
        long totals = this.getCount(filter);
        return new Page(entitys, pageNumber, pageSize, totals);
    }

    public Long getCount() {
        return this.getCount((Map)null);
    }

    public Long getCount(Map<String, Object> filter) {
        StringBuilder _hql = new StringBuilder("SELECT COUNT(1) FROM " + this.entityName);
        List<Object> params = new ArrayList();
        if (Collections.isNotEmpty(filter)) {
            Set<Entry<String, Object>> set = filter.entrySet();
            Iterator var5 = set.iterator();

            while(var5.hasNext()) {
                Entry<String, Object> entry = (Entry)var5.next();
                _hql.append(" AND " + (String)entry.getKey() + " = ?");
                params.add(entry.getValue());
            }
        }

        String hql = _hql.toString().replaceFirst("AND", "WHERE");
        Query query = this.getCurrentSession().createQuery(hql);

        for(int i = 0; i < params.size(); ++i) {
            query.setParameter(i, params.get(i));
        }

        return (Long)query.uniqueResult();
    }
}
